package com.listeningframework.boot.autoconfigure.orm.jpa.search;

import java.math.BigDecimal;
import java.util.List;

import com.google.common.collect.Lists;
import com.listeningframework.boot.autoconfigure.orm.jpa.search.filters.BigDecimalSearchFilter;
import com.listeningframework.boot.autoconfigure.orm.jpa.search.filters.BooleanSearchFilter;
import com.listeningframework.boot.autoconfigure.orm.jpa.search.filters.IntegerSearchFilter;
import com.listeningframework.boot.autoconfigure.orm.jpa.search.filters.LongSearchFilter;
import com.listeningframework.boot.autoconfigure.orm.jpa.search.filters.SearchFilter;
import com.listeningframework.boot.autoconfigure.orm.jpa.search.filters.StringSearchFilter;

public class SpecBuilder {
    private List<SearchFilter<?>> searchList = Lists.newArrayList();

    private SpecBuilder() {

    }

    public static SpecBuilder newinstance() {
        return new SpecBuilder();
    }

    public SpecBuilder addFilter(String name, Operations op, Object val) {
        if (val instanceof String) {
            String value = (String) val;
            searchList.add(new StringSearchFilter(name, op, value));
        } else if (val instanceof Integer) {
            Integer value = (Integer) val;
            searchList.add(new IntegerSearchFilter(name, op, value));
        } else if (val instanceof Long) {
            Long value = (Long) val;
            searchList.add(new LongSearchFilter(name, op, value));
        } else if (val instanceof BigDecimal) {
            BigDecimal value = (BigDecimal) val;
            searchList.add(new BigDecimalSearchFilter(name, op, value));
        } else if (val instanceof Boolean) {
            Boolean value = (Boolean) val;
            searchList.add(new BooleanSearchFilter(name, op, value));
        }
        return this;
    }

    public SpecBuilder addEQ(String name, Object val) {
        this.addFilter(name, Operations.EQ, val);
        return this;
    }

    public SpecBuilder addLIKE(String name, Object val) {
        this.addFilter(name, Operations.LIKE, val);
        return this;
    }

    public SpecBuilder addGT(String name, Object val) {
        this.addFilter(name, Operations.GT, val);
        return this;
    }

    public SpecBuilder addLE(String name, Object val) {
        this.addFilter(name, Operations.LTE, val);
        return this;
    }

    public SpecBuilder addFilter(SearchFilter<?> filter) {
        searchList.add(filter);
        return this;
    }

    public List<SearchFilter<?>> build() {
        return searchList;
    }

    public void reset() {
        searchList.clear();
    }
}
